﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Utility.FSM
{
	public interface IAgentScript
	{
		void OnInit (Agent agent);
		void OnDispose (Agent agent);

		void OnEnterState (Agent agent, State state, object context);
		void OnExitState (Agent agent, State state, object context);
		void OnArriveState (Agent agent, State state, object context);
		void OnUpdate (Agent agent, State state, object context);

	}

	public class BaseAgentScript : IAgentScript
	{
		public Agent FSMAgent { get; protected set; }

		public virtual void OnInit (Agent agent)
		{
			FSMAgent = agent;
		}

		public virtual void OnDispose (Agent agent)
		{

		}

		public virtual void OnArriveState (Agent agent, State state, object context) { }
		public virtual void OnEnterState (Agent agent, State state, object context) { }
		public virtual void OnExitState (Agent agent, State state, object context) { }
		public virtual void OnUpdate (Agent agent, State state, object context) { }

		#region function shortcut
		public State State => FSMAgent.State;

		public bool SendSignal (string signal, object context = null)
		{
			return FSMAgent.SendSignal (signal, context);
		}

		public void ConsumeSignal ()
		{
			FSMAgent.ConsumeSignal ();
		}

		public void Update (object context = null)
		{
			FSMAgent.Update (context);
		}

		public void MoveTo (State targetState, object context = null)
		{
			FSMAgent.MoveTo (targetState, context);
		}

		public void MoveTo (string targetStateName, object context = null)
		{
			FSMAgent.MoveTo (targetStateName, context);
		}
		
		public void MoveTo(State target_0,State target_1,object context=null)
		{
			FSMAgent.MoveTo (target_0, target_1, context);
		}

		public void Reenter(State state,object context=null)
		{
			FSMAgent.Reenter (state, context);
		}

		public void MoveToSibling (string targetStateName, object context = null)
		{
			FSMAgent.MoveToSibling (targetStateName, context);
		}

		public void MoveToSibling (string targetStateName, bool reenterSelf, object context = null)
		{
			FSMAgent.MoveToSibling (targetStateName, reenterSelf, context);
		}

		/// <summary>
		/// Enter target state, which must be an descendant state
		/// </summary>
		/// <param name="state"></param>
		public void EnterState (State state, object context = null)
		{
			FSMAgent.EnterState (state, context);
		}

		public void EnterState (string stateName, object context = null)
		{
			FSMAgent.EnterState (stateName, context);
		}

		/// <summary>
		/// Exit current state
		/// </summary>
		/// <param name="context"></param>
		public void ExitState (object context = null)
		{
			FSMAgent.ExitState (context);
		}

		/// <summary>
		/// Exit the state, the state must be one of the upper state
		/// </summary>
		/// <param name="state"></param>
		public void ExitState (State state, object context = null)
		{
			FSMAgent.ExitState (state, context);
		}

		public void ExitState (string stateName, object context = null)
		{
			FSMAgent.ExitState (stateName, context);
		}

		/// <summary>
		/// From null state enter the Root state
		/// </summary>
		/// <param name="context"></param>
		public void EnterFSM (object context = null)
		{
			FSMAgent.EnterFSM (context);
		}

		/// <summary>
		/// Exit from current state up to the Root
		/// Until state is null
		/// </summary>
		/// <param name="context"></param>
		public void ExitFSM (object context = null)
		{
			FSMAgent.ExitFSM (context);
		}

		#endregion
	}
}